package com.data.modules.es.service.impl;

import cn.easyes.common.enums.FieldStrategy;
import cn.easyes.common.utils.ExceptionUtils;
import cn.easyes.common.utils.FastJsonUtils;
import cn.easyes.core.biz.EntityFieldInfo;
import cn.easyes.core.biz.EntityInfo;
import cn.easyes.core.biz.PageInfo;
import cn.easyes.core.cache.BaseCache;
import cn.easyes.core.conditions.LambdaEsQueryWrapper;
import cn.easyes.core.toolkit.EntityInfoHelper;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.data.modules.es.convert.AcsConverter;
import com.data.modules.es.entity.ACSDocument;
import com.data.modules.es.entity.Acs;
import com.data.modules.es.entity.AcsEntity;
import com.data.modules.es.mapper.DemoMapper;
import com.data.modules.es.mapper.DocumentMapper;
import com.data.modules.es.service.IAcsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

@SuppressWarnings("ALL")
@Slf4j
@Service
public class AcsServiceImpl implements IAcsService {

    @Autowired
    private AcsConverter acsConverter;
    @Autowired
    private DemoMapper demoMapper;
    @Resource
    private DocumentMapper esDocument;





    @Override
    public void insertBatchDB2ES() {
        LambdaQueryWrapper<AcsEntity> query =  new LambdaQueryWrapper<>();
        //自增排序
        query.orderByAsc(AcsEntity::getId);
        //List<AcsEntity> list = demoMapper.selectList(query);

        IPage<AcsEntity> page = new Page<AcsEntity>(1,100);
        IPage<AcsEntity> pageList = demoMapper.selectPage(page, query);
        List<AcsEntity> list = pageList.getRecords();
        log.info("===getPages:{}",page.getPages());
        this.inertDB2ES(list);

        long pageSize = page.getPages();
        if(pageSize > 1){
            //循环写入
            for(long i = 2;i <= pageSize;i ++){
                page = new Page<AcsEntity>(i,100);
                list =  demoMapper.selectPage(page,query).getRecords();
                this.inertDB2ES(list);
            }
        }
        /*AcsEntity dto = null;
        Acs acs = new Acs();
        acs = acsConverter.entity2ES(dto);*/

       /* for(int i = 0;i < list.size();i ++){
            AcsEntity dto = list.get(i);
            Acs acs = new Acs();//acsConverter.entity2ES(dto);
            acs = acsConverter.entity2ES(dto);
            log.info("{}:{}",i, JSON.toJSON(acs));
            ACSDocument doc = new ACSDocument();
            try{
                //acsES.insert(acs);
                doc.setId(acs.getId());
                doc.setTitle(acs.getTitle());
                doc.setContent(acs.getAbstractTextNoHtmllabel());
                doc.setCreator(acs.getAuthorName());
                doc.setGmtCreate(acs.getCrawl_time());
                esDocument.insert(doc);
            }catch (Exception e){
                log.info("2222222acs:{}", JSON.toJSON(doc));
                log.error(e.getMessage(),e);
            }
        }
       }*/
    }

    @Override
    public PageInfo<ACSDocument> pageQuery(String title, Integer pageNum) {
        if(pageNum == null || pageNum > 50 || pageNum <=0){
            //取第一页
            pageNum = 1;
        }
        title = title.toLowerCase();
        // 实际开发中会把这些逻辑写进service层 这里为了演示方便就不创建service层了
        LambdaEsQueryWrapper<ACSDocument> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.eq(ACSDocument::getTitle, title);
        //return esDocument.selectList(wrapper);
        //每页20条数据
        PageInfo<ACSDocument> list = esDocument.pageQuery(wrapper, pageNum, 20);
        return list;
    }

    @Override
    public PageInfo<ACSDocument> pageHighlightSearch(String content, Integer pageNum) {
        if(pageNum == null || pageNum > 50 || pageNum <=0){
            //取第一页
            pageNum = 1;
        }

        LambdaEsQueryWrapper<ACSDocument> wrapper = new LambdaEsQueryWrapper<>();

        wrapper.match(ACSDocument::getContent, content);
        //每页20条数据
        PageInfo<ACSDocument> list = esDocument.pageQuery(wrapper,pageNum,20);
        return list;
    }

    private void inertDB2ES(List<AcsEntity> list) {
        if(list == null || list.size() == 0){
            return ;
        }
        Long start = System.currentTimeMillis();
        try{
            List<ACSDocument> docList = new ArrayList<>();
            list.stream().forEach(dto->{
                ACSDocument doc = new ACSDocument();
                //BeanUtil.copyProperties(dto,doc);
                doc.setId(dto.getId());
                doc.setTitle(dto.getTitle());
                doc.setContent(dto.getAbstractTextNoHtmllabel());
                doc.setCreator(dto.getAuthorName());
                doc.setGmtCreate(dto.getCrawl_time());
                docList.add(doc);
            });
            esDocument.insertBatch(docList);
        }catch (Exception e){
            List<String> errorIds = list.stream().map(dto -> dto.getId()).collect(Collectors.toList());
            log.error("===errorIds:{}",JSON.toJSON(errorIds));
            log.error(e.getMessage(),e);
        }
        log.info("====inertDB2ES====={}",(System.currentTimeMillis() - start) );
    }


    private Class<T> entityClass;

    private String buildJsonIndexSource(T entity) {
        EntityInfo entityInfo = EntityInfoHelper.getEntityInfo(this.entityClass);
        List<EntityFieldInfo> fieldList = entityInfo.getFieldList();
        Set<String> excludeColumn = new HashSet();

        fieldList.forEach((field) -> {
            String column = field.getColumn();
            Method invokeMethod = BaseCache.getterMethod(this.entityClass, column);
            FieldStrategy fieldStrategy = field.getFieldStrategy();

            try {
                Object invoke;
                if (FieldStrategy.NOT_NULL.equals(fieldStrategy)) {
                    invoke = invokeMethod.invoke(entity);
                    if (Objects.isNull(invoke)) {
                        excludeColumn.add(column);
                    }
                } else if (FieldStrategy.NOT_EMPTY.equals(fieldStrategy)) {
                    invoke = invokeMethod.invoke(entity);
                    if (Objects.isNull(invoke)) {
                        excludeColumn.add(column);
                    } else if (invoke instanceof String) {
                        String strValue = (String)invoke;
                        if (cn.easyes.common.utils.StringUtils.isEmpty(strValue)) {
                            excludeColumn.add(column);
                        }
                    }
                }

            } catch (Exception var9) {
                throw ExceptionUtils.eee("buildJsonIndexSource exception, entity:%s", var9, new Object[]{entity.toString()});
            }
        });
        ArrayList<SerializeFilter> serializeFilters = new ArrayList();
        Optional var10000 = Optional.ofNullable((List)entityInfo.getClassSimplePropertyPreFilterMap().get(this.entityClass));
        Objects.requireNonNull(serializeFilters);
        //var10000.ifPresent(serializeFilters::addAll);
        SimplePropertyPreFilter simplePropertyPreFilter = FastJsonUtils.getSimplePropertyPreFilter(entity.getClass(), excludeColumn);
        var10000 = Optional.ofNullable(simplePropertyPreFilter);
        Objects.requireNonNull(serializeFilters);
        //var10000.ifPresent(serializeFilters::add);
        return JSON.toJSONString(entity, (SerializeFilter[])serializeFilters.toArray(new SerializeFilter[0]), new SerializerFeature[]{SerializerFeature.WriteMapNullValue});
    }



}
